package com.banksoft.admin.service.impl;

import com.banksoft.admin.SystemCache;
import com.banksoft.admin.bean.*;
import com.banksoft.admin.dao.*;
import com.banksoft.admin.entity.*;
import com.banksoft.admin.service.OrderService;
import com.banksoft.common.ConfigHelper;
import com.banksoft.front.bean.*;
import com.banksoft.front.util.SendMessageUtil;
import com.banksoft.front.util.WeixinUtil;
import com.banksoft.front.util.WxSupportUtil;
import com.banksoft.util.DateUtil;
import com.banksoft.util.StringNumber;
import com.banksoft.util.StringUtil;
import com.banksoft.util.UUIDFactory;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.spel.ast.Projection;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by vanjoger on 2017/1/2.
 */
@Service
@Transactional
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderDao orderDao;
    @Autowired
    BaseMyBatisDao baseMyBatisDao;
    @Autowired
    UserDao userDao;
    @Autowired
    OrderProductDao orderProductDao;
    @Autowired
    UserMoneyDao userMoneyDao;
    @Autowired
    UserAddressDao userAddressDao;

    private ExecutorService executor = Executors.newFixedThreadPool(2);

    private String templateMessageUrl = "http://www.boaishangcheng.com/wx/autoLogin?id=";

    @Override
    public List<ProductBean> preOrder(String ids) {
        List<ProductBean> data = new ArrayList<>();
        if(StringUtil.isNotNull(ids)){
            String[] arrays = ids.split(",");
            for(String array:arrays){
                String[] idnum = array.split("-");
                if(idnum!=null&&idnum.length>1){
                    String id = idnum[0];
                    String num = idnum[1];
                    Product product = this.baseMyBatisDao.findById(ProductDao.class,id);
                    if(product!=null){
                        ProductBean bean = new ProductBean();
                        bean.setId(product.getId());
                        bean.setName(product.getName());
                        String images = product.getImages();
                        String image = "";
                        if(StringUtil.isNotNull(images)){
                            image = images.split("\\|")[0];
                        }
                        bean.setImage(image);
                        bean.setNum(num);
                        bean.setPrice(product.getPrice());
                        bean.setTotalPrice(StringNumber.mul(product.getPrice(),num));
                        data.add(bean);
                    }
                }
            }
        }
        return data;
    }

    @Override
    public Order save(String userId, String ids, String userName, String telephone, String province, String provinceName, String city, String cityName, String area, String areaName,
                      String address, String remark, String bonus_amount, String post_amount) {
        User user = baseMyBatisDao.findById(UserDao.class,userId);
        if(user==null)
            throw new NullPointerException();
        String[] idnum = ids.split(",");
        String totalMoney = post_amount;

        Order order = new Order();
        order.setId(UUIDFactory.random());
        order.setMemberId(user.getId());
        order.setMemberAccount(user.getNickName());
        order.setNo(DateUtil.getFormatDate(new Date(),"yyyyMMddHHmmssSSS"));

        if(idnum!=null&&idnum.length>0){
            for(String str:idnum){
                String[] arrays = str.split("-");
                String id = arrays[0];
                String num = arrays[1];

                Product product = this.baseMyBatisDao.findById(ProductDao.class,id);

                OrderProduct orderProduct = new OrderProduct();
                orderProduct.setId(UUIDFactory.random());
                orderProduct.setOrderId(order.getId());
                orderProduct.setProductId(id);
                orderProduct.setProductName(product.getName());
                orderProduct.setNum(num);
                this.baseMyBatisDao.insert(OrderProductDao.class,orderProduct);

                totalMoney = StringNumber.add(totalMoney,StringNumber.mul(product.getPrice(),num));
            }
        }
        order.setType("0");
        order.setTotalMoney(totalMoney);
        order.setStatus(OrderStatus.Create.name());
        order.setPayAmount(totalMoney);
        order.setBonusAmount("0");
        order.setPostAmount(post_amount);
        order.setCreateTime(new Date().getTime());
        //计算实际付款
        if(!bonus_amount.equals("0")){//使用购物币支付
            List<UserMoney> moneys = userMoneyDao.findByUserId(user.getId());
            UserMoney money = null;
            if(StringUtil.isNotEmpty(moneys))
                money = moneys.get(0);
            if(money!=null){//购物币存在
                String amount = totalMoney;
                String beforeBonus = money.getBonus();
                String beforeCash = money.getCash();
                if((Float.parseFloat(beforeBonus)+Float.parseFloat(beforeCash))>=Float.parseFloat(totalMoney)){//余额满足
                    order.setPayAmount("0");
                    order.setBonusAmount(totalMoney);
                    order.setStatus(OrderStatus.Pay.name());
                    order.setPayTime(new Date().getTime());

                    if(Float.parseFloat(beforeBonus)>=Float.parseFloat(totalMoney)){//购物币满足
                        money.setBonus(StringNumber.sub(beforeBonus,totalMoney));
                    }else{//先减去购物币  再减去现金币
                        String left = StringNumber.sub(totalMoney,beforeBonus);
                        money.setBonus("0");
                        money.setCash(StringNumber.sub(money.getCash(), left));
                    }
                }else{
                    order.setPayAmount(StringNumber.sub(StringNumber.sub(totalMoney,beforeBonus),beforeCash));
                    order.setBonusAmount(StringNumber.add(beforeBonus,beforeCash));
                    //重置成0
                    money.setBonus("0");
                    money.setCash("0");
                    amount = StringNumber.add(beforeBonus,beforeCash);
                }

                this.baseMyBatisDao.update(UserMoneyDao.class,money);
                //保存资金流水
                saveAmountLog(user,beforeCash,beforeBonus,"-"+amount,money,AmountType.OrderFee.name());
            }
        }
        order.setUserName(userName);
        order.setProvince(province);
        order.setProvinceName(provinceName);
        order.setCity(city);
        order.setCityName(cityName);
        order.setArea(area);
        order.setAreaName(areaName);
        order.setTelephone(telephone);
        order.setAddress(address);
        order.setRemark(remark);
        this.baseMyBatisDao.insert(OrderDao.class,order);

        //保存收货地址
        //检测区县是否存在
        UserAddress userAddress = new UserAddress();//不存在
        userAddress.setId(UUIDFactory.random());
        userAddress.setUserId(userId);
        userAddress.setUserName(userName);
        userAddress.setProvince(province);
        userAddress.setProvinceName(provinceName);
        userAddress.setCity(city);
        userAddress.setCityName(cityName);
        userAddress.setArea(area);
        userAddress.setAreaName(areaName);
        userAddress.setTelephone(telephone);
        userAddress.setAddress(address);

        List<UserAddress> userAddressList = this.userAddressDao.listByUserId(userId);
        List<UserAddress> addresses = this.userAddressDao.findByUserIdAndAreaId(userId,area);
        if(StringUtil.isNotEmpty(userAddressList)){//收货地址存在
            if(!StringUtil.isNotEmpty(addresses)){//该区县不存在
                userAddress.setIsDefault("1");//不是默认
                this.baseMyBatisDao.insert(UserAddressDao.class,userAddress);
            }
        }else{
            userAddress.setIsDefault("0");//不是默认
            this.baseMyBatisDao.insert(UserAddressDao.class,userAddress);
        }

        if(OrderStatus.Pay.name().equals(order.getStatus())) {//支付成功
            if(order.getType().equals("0")) {// 普通订单 计算返利
                user.setIsMember("1");
                this.baseMyBatisDao.update(UserDao.class,user);
                executor.execute(new CalFlThread(order));
            }else{
                executor.execute(new CalSjThread(order));
            }
        }

        return order;
    }

    /**
     * 保存资金流水
     * @param user
     * @param beforeBonus
     * @param amount
     * @param money
     */
    private void saveAmountLog(User user, String beforeCash,String beforeBonus, String amount, UserMoney money,String type) {
        AmountLog log = new AmountLog();
        log.setId(UUIDFactory.random());
        log.setUserId(user.getId());
        log.setUserName(user.getNickName());
        log.setCreateTime(new Date().getTime());
        log.setType(type);
        log.setBeforeCash(beforeCash);
        log.setBeforeBonus(beforeBonus);
        log.setBeforeFrozenAmount(money.getFrozenAmount());
        log.setAfterCash(money.getCash());
        log.setAfterBonus(money.getBonus());
        log.setAfterFrozenAmount(money.getFrozenAmount());
        log.setCash(amount);
        log.setBonus("0");
        this.baseMyBatisDao.insert(AmountLogDao.class,log);
    }

    //组装群发消息时的文本消息
    private String createTextMessage(String openId, String content) {
        String mes = "{\n" +
                "    \"touser\":\""+openId+"\",\n" +
                "    \"msgtype\":\"text\",\n" +
                "    \"text\":\n" +
                "    {\n" +
                "         \"content\":\""+content+"\"\n" +
                "    }\n" +
                "}";
        return mes;
    }


    @Override
    public void updateOrder(String orderId, String status) {
        List<Order> orderList = this.orderDao.listByOrderNo(orderId);
                //this.baseMyBatisDao.findById(OrderDao.class,orderId);
        if(StringUtil.isNotEmpty(orderList)){
            Order order = orderList.get(0);
            if(order.getStatus().equals(status))
                return ;
            order.setStatus(status);
            order.setPayTime(new Date().getTime());
            this.baseMyBatisDao.update(OrderDao.class,order);

            if(OrderStatus.Pay.name().equals(status)) {//支付成功
                User user = this.baseMyBatisDao.findById(UserDao.class,order.getMemberId());
                if(user!=null){
                    /*List<Order> orderlist = orderDao.listByUserId(order.getMemberId());
                    if(StringUtil.isNotEmpty(orderlist)&&orderlist.size()==1){//第一次下单
                        List<User> userlist = this.userDao.list(new HashMap());
                        String message = "恭喜你成为荩美国际的第【"+(userlist.size()+1)+"】位会员";
                        if(StringUtil.isNotNull(user.getRecommendId())&&!user.getId().equals(user.getRecommendId())){
                            User upuser = this.baseMyBatisDao.findById(UserDao.class,user.getRecommendId());
                            if(upuser!=null)
                                message += ",你的上级是："+upuser.getNickName()+"。";
                        }
                        try {
                           String result =  WxSupportUtil.kfSendMessage(SystemCache.getWxSetting(),createTextMessage(user.getOpenId(),message));
                            System.out.println("****  "+result);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }*/

                    user.setIsMember("1");
                    this.baseMyBatisDao.update(UserDao.class,user);
                }
                if(order.getType().equals("0")) {// 普通订单 计算返利
                    executor.execute(new CalFlThread(order));
                }else{
                    List<UserMoney> moneys = userMoneyDao.findByUserId(user.getId());
                    UserMoney money = null;
                    if(StringUtil.isNotEmpty(moneys))
                        money = moneys.get(0);
                    String bonusAmount = order.getBonusAmount();
                    if(StringUtil.isNotNull(bonusAmount)&&money!=null){
                        if(Float.parseFloat(bonusAmount)>0){
                            String bonus = money.getBonus();
                            String cash = money.getCash();
                            String amount = StringNumber.add(bonus,cash);
                            if(Float.parseFloat(bonusAmount)>Float.parseFloat(amount)){//支付的余额大于余额和购物币
                                money.setCash("0");
                                money.setBonus("0");
                            }else{
                                amount = bonusAmount;
                                if(Float.parseFloat(bonusAmount)>Float.parseFloat(bonus)){
                                    String left = StringNumber.sub(bonusAmount,bonus);
                                    money.setBonus("0");
                                    money.setCash(StringNumber.sub(cash,left));
                                }else{
                                     money.setBonus(StringNumber.sub(bonus,bonusAmount));
                                }
                            }
                            this.baseMyBatisDao.update(UserMoneyDao.class,money);
                            saveAmountLog(user,cash,bonus,"-"+amount,money,AmountType.UpdateFee.name());
                        }
                    }
                    executor.execute(new CalSjThread(order));
                }
            }
        }
    }


    @Override
    public JSONObject saveSjOrder(String type, String remark, String userId, String province, String provinceName, String city, String cityName, String area, String areaName, String amount, String userName, String telephone, String idCard, String bankName, String cardName, String cardNo, String addressProvince, String addressProvinceName, String addressCity, String addressCityName, String addressArea, String addressAreaName,String addressStr) {
        User user = baseMyBatisDao.findById(UserDao.class,userId);
        ConfigHelper instance = ConfigHelper.GetInstance();
        String totalMoney = "0";
        if(!StringUtil.isNotNull(type))
            return StringUtil.FmtResult(false,"请选择要升级的角色",null);

        if(!MemberType.Customer.name().equals(user.getType())){//不是普通消费者
            if(MemberType.Gold.name().equals(type)){//要升级金牌会员
                if(MemberType.General.name().equals(user.getType())){//是全国总代
                    return StringUtil.FmtResult(false,"您已经是全国总代，无需升级",null);
                }
                if(MemberType.Gold.name().equals(user.getType())){//是全国总代
                    return StringUtil.FmtResult(false,"您已经是金牌代理，无需升级",null);
                }
            }
            if(MemberType.General.equals(type)){//升级全国总代
                if(!MemberType.Gold.name().equals(user.getType())){//不是金牌会员
                    return StringUtil.FmtResult(false,"您已经是全国总代，无需升级",null);
                }
            }
        }

        if (MemberType.Gold.name().equals(type)) {
            totalMoney = instance.GetConfig("Gold_Fee");
        } else if (MemberType.General.name().equals(type)) {
            totalMoney = instance.GetConfig("General_Fee");
        }

        user.setIdCard(idCard);
        user.setBankName(bankName);
        user.setCardName(cardName);
        user.setCardNo(cardNo);
        user.setUserProvince(province);
        user.setUserProvinceName(provinceName);
        user.setUserCity(city);
        user.setUserCityName(cityName);
        user.setUserArea(area);
        user.setUserAreaName(areaName);
        this.baseMyBatisDao.update(UserDao.class,user);

        List<UserAddress> userAddresses = this.userAddressDao.listByUserId(userId);
        //如果存在此地区的收货地址
        boolean find = false;
        if(StringUtil.isNotEmpty(userAddresses)){
            for(UserAddress address:userAddresses){
                if(address.getArea().equals(addressArea)){
                    find = true;
                    address.setIsDefault("0");
                    address.setUserName(userName);
                    address.setTelephone(telephone);
                    address.setAddress(addressStr);
                }else{
                    address.setIsDefault("1");
                }
                this.baseMyBatisDao.update(UserAddressDao.class,address);
            }
        }
        if(!find){
            UserAddress address = new UserAddress();
            address.setId(UUIDFactory.random());
            address.setUserId(user.getId());
            address.setUserName(user.getNickName());
            address.setTelephone(telephone);
            address.setProvince(addressProvince);
            address.setProvinceName(addressProvinceName);
            address.setCity(addressCity);
            address.setCityName(addressCityName);
            address.setArea(addressArea);
            address.setAreaName(addressAreaName);
            address.setIsDefault("0");
            address.setAddress(addressStr);
            this.baseMyBatisDao.insert(UserAddressDao.class,address);
        }


        Order order = new Order();
        order.setId(UUIDFactory.random());
        order.setMemberId(user.getId());
        order.setMemberAccount(user.getNickName());
        order.setNo(DateUtil.getFormatDate(new Date(),"yyyyMMddHHmmssSSS"));
        order.setType("1");
        order.setProductName(type);
        order.setTotalMoney(totalMoney);
        order.setPayAmount(totalMoney);
        order.setBonusAmount("0");
        order.setStatus(OrderStatus.Create.name());

        if(!amount.equals("0")){//使用购物币支付
            List<UserMoney> moneys = userMoneyDao.findByUserId(user.getId());
            UserMoney money = null;
            if(StringUtil.isNotEmpty(moneys))
                money = moneys.get(0);
            if(money!=null){//购物币存在
                String beforeBonus = money.getBonus();
                String beforeCash = money.getCash();
                amount = totalMoney;
                if((Float.parseFloat(beforeBonus)+Float.parseFloat(beforeCash))>=Float.parseFloat(totalMoney)){//余额满足
                    order.setPayAmount("0");
                    order.setBonusAmount(totalMoney);
                    order.setStatus(OrderStatus.Pay.name());
                    order.setPayTime(new Date().getTime());

                    if(Float.parseFloat(beforeBonus)>=Float.parseFloat(totalMoney)){//购物币满足
                        money.setBonus(StringNumber.sub(beforeBonus,totalMoney));
                    }else{//先减去购物币  再减去现金币
                        String left = StringNumber.sub(totalMoney,beforeBonus);
                        money.setBonus("0");
                        money.setCash(StringNumber.sub(money.getCash(),left));
                    }
                }else{//如果余额不足  待支付成功后减去资金
                    order.setPayAmount(StringNumber.sub(StringNumber.sub(totalMoney,beforeBonus),beforeCash));
                    order.setBonusAmount(StringNumber.add(beforeBonus,beforeCash));
                    //重置成0
                    money.setBonus("0");
                    money.setCash("0");
                    amount = StringNumber.add(beforeBonus,beforeCash);
                }
                this.baseMyBatisDao.update(UserMoneyDao.class,money);
                //保存资金流水
                saveAmountLog(user,beforeCash,beforeBonus,"-"+amount,money,AmountType.UpdateFee.name());
            }
        }
        order.setCreateTime(new Date().getTime());
        order.setUserName(user.getNickName());
        order.setProvince(province);
        order.setProvinceName(provinceName);
        order.setCity(city);
        order.setCityName(cityName);
        order.setArea(area);
        order.setAreaName(areaName);
       // order.setTelephone(telephone);
        order.setAddress(addressStr);
        order.setRemark(remark);
        this.baseMyBatisDao.insert(OrderDao.class,order);

        if(OrderStatus.Pay.name().equals(order.getStatus())) {//支付成功
            if(user!=null){
                if(!StringUtil.isNotNull(user.getIsMember())||(!"1".equals(user.getIsMember()))){//不是正式会员
                    user.setIsMember("1");
                    this.baseMyBatisDao.update(UserDao.class,user);
                }
            }
            if(order.getType().equals("0")) {// 普通订单 计算返利
                executor.execute(new CalFlThread(order));
            }else{
                executor.execute(new CalSjThread(order));
            }
            return StringUtil.FmtResult(true,"升级成功",order);
        }else{
            return StringUtil.FmtResult(true,"请支付完成升级！",order);
        }


    }

    @Override
    public List<Order> query(Map map) {
        return this.orderDao.query(map);
    }

    @Override
    public Page queryPage(String userId, int pageNo, int pageSize, String isToday) {
        Page page = new Page(pageNo,pageSize);

        Map map = new HashMap();
        map.put("userId",userId);
        map.put("type","0");//普通订单
        map.put("start",page.getStart());
        map.put("size",page.getPageSize());
        if(StringUtil.isNotNull(isToday)&&isToday.equals("0")){
            Long startDate = DateUtil.getLongFormStrDate(DateUtil.getFormatDate(new Date(), "yyyy-MM-dd") + " 00:00:00");
            Long endDate = DateUtil.getLongFormStrDate(DateUtil.getFormatDate(new Date(), "yyyy-MM-dd") + " 23:59:59");
            map.put("startDate", startDate);
            map.put("endDate", endDate);
        }

        List<Order> list = this.orderDao.queryPage(map);
        List<OrderBean> data = new ArrayList<>();
        for(Order order:list){
            OrderBean bean = new OrderBean();
            bean.setId(order.getId());
            bean.setNo(order.getNo());
            bean.setCreateTime(order.getCreateTime());
            bean.setStatus(order.getStatus());
            bean.setTotalMoney(order.getTotalMoney());

            List<OrderProduct> productList = this.orderProductDao.listByOrderId(order.getId());
            if(StringUtil.isNotEmpty(productList)){
                OrderProduct op = productList.get(0);
                Product product = this.baseMyBatisDao.findById(ProductDao.class,op.getProductId());
                if(product!=null){
                    bean.setProductName(product.getName());
                    String images = product.getImages();
                    if(StringUtil.isNotNull(images)) {
                        String[] arrays = images.split("\\|");
                        bean.setProductImage(arrays[0]);
                    }
                    bean.setProductPrice(product.getPrice());
                    bean.setProductNum(op.getNum());
                }
            }
            data.add(bean);
        }
        Integer total = this.orderDao.countPage(map);
        page.setData(data);
        page.setTotal(total);
        return page;
    }

    @Override
    public List<Order> listOrderByStatus(String status) {
        return this.orderDao.listOrderByStatus(status);
    }

    @Override
    public List<Order> count(Map map) {
        return this.orderDao.count(map);
    }

    /**
     * 发送模板消息
     * @param order
     */
    @Override
    public void sendTextMessage(Order order) {
        String userId = order.getMemberId();
        User user = this.baseMyBatisDao.findById(UserDao.class,userId);
        if(user!=null){
            if(StringUtil.isNotNull(user.getOpenId())){//不存在openId
                // 回复文本消息
                TextMessage textMessage = new TextMessage();
                textMessage.setToUserName(user.getOpenId());
                textMessage.setFromUserName(SystemCache.AppId);
                textMessage.setCreateTime(System.currentTimeMillis());
                textMessage.setMsgType(WxMesType.text.name());
                textMessage.setFuncFlag(0);
                if(StringUtil.isNotNull(order.getBillNo())){
                    textMessage.setContent("您的订单已发货，快递方式是邮政小包，运单号是："+order.getBillNo()+"，查询物流及代理咨询请联系：4000543733");
                }else {
                    textMessage.setContent("您的订单已发货，查询物流及代理咨询请联系：4000543733");
                }
               String  sendMessage = MessageUtil.keMessageToXml(textMessage);
                try {
                    String result =  WeixinUtil.kfSendMessage(SystemCache.getWxSetting(),sendMessage);
                    System.out.println("***** "+result);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public List<Order> listByUserIds(String[] ids) {
        return this.orderDao.listByUserIds(ids);
    }

    @Override
    public Page queryTeamOrderPage(String userId, String isToday) {
        Page page = new Page(1,50);

        List<Order> list = new ArrayList<>();
        getTotalOrder(userId,list);
        OrderCompare compare = new OrderCompare();
        Collections.sort(list,compare);

        List<OrderBean> data = new ArrayList<>();
        if(StringUtil.isNotEmpty(list)) {
            for (Order order : list) {
                OrderBean bean = new OrderBean();
                bean.setId(order.getId());
                bean.setNo(order.getNo());
                bean.setCreateTime(order.getCreateTime());
                bean.setStatus(order.getStatus());
                bean.setTotalMoney(order.getTotalMoney());

                List<OrderProduct> productList = this.orderProductDao.listByOrderId(order.getId());
                if (StringUtil.isNotEmpty(productList)) {
                    OrderProduct op = productList.get(0);
                    Product product = this.baseMyBatisDao.findById(ProductDao.class, op.getProductId());
                    if (product != null) {
                        bean.setProductName(product.getName());
                        String images = product.getImages();
                        if (StringUtil.isNotNull(images)) {
                            String[] arrays = images.split("\\|");
                            bean.setProductImage(arrays[0]);
                        }
                        bean.setProductPrice(product.getPrice());
                        bean.setProductNum(op.getNum());
                    }
                }
                data.add(bean);
            }
        }else{
            page.setPageNo(1);
        }
        page.setData(data);

        return page;

    }

    @Override
    public void cancelOrder(String orderId) {
        Order order = this.baseMyBatisDao.findById(OrderDao.class,orderId);
        if(order!=null){
            if(OrderStatus.Create.name().equals(order.getStatus())){//只取消待支付订单
                order.setStatus(OrderStatus.Close.name());
                this.baseMyBatisDao.update(OrderDao.class,order);

                if(StringUtil.isNotNull(order.getBonusAmount())&&!(order.getBonusAmount().equals("0"))){
                    String userId = order.getMemberId();
                    User user = this.baseMyBatisDao.findById(UserDao.class,userId);
                    if(user!=null){
                        List<UserMoney> moneys = userMoneyDao.findByUserId(userId);
                        UserMoney money = null;
                        if(StringUtil.isNotEmpty(moneys))
                            money = moneys.get(0);
                        if(money!=null) {//购物币存在
                            String beforeBonus = money.getBonus();
                            String beforeCash = money.getCash();

                            money.setBonus(StringNumber.add(money.getBonus(), order.getBonusAmount()));//将支付余额退回至账户中
                            this.baseMyBatisDao.update(UserMoneyDao.class, money);
                            //保存资金流水
                            saveAmountLog(user, beforeCash, beforeBonus, order.getBonusAmount(), money, AmountType.TkFee.name());
                        }
                    }
                }
            }
        }
    }

    @Override
    public Integer countQueryPage(Map params) {
        return this.orderDao.countPage(params);
    }

    @Override
    public List<Order> queryByPage(Map params) {
        return this.orderDao.queryPage(params);
    }

    @Override
    public List<Order> listByOrderNo(String orderNo) {
        return orderDao.listByOrderNo(orderNo);
    }

    private void getTotalOrder(String userId,List<Order> total){
        String startDate = DateUtil.getFormatDate(new Date(),"yyyy-MM-dd")+" 00:00:00";
        String endDate = DateUtil.getFormatDate(new Date(),"yyyy-MM-dd")+" 23:59:59";
        Map map = new HashMap();
        map.put("startDate",DateUtil.getLongFormStrDate(startDate));
        map.put("endDate",DateUtil.getLongFormStrDate(endDate));
        map.put("type","0");//普通订单
        map.put("ids",new String[]{userId});
        map.put("status",new String[]{OrderStatus.Pay.name(),OrderStatus.Send.name(),OrderStatus.Suc.name()});

        List<Order> orders = this.orderDao.count(map);
        if(StringUtil.isNotEmpty(orders))
            total.addAll(orders);

        List<User> list = this.userDao.listByRecommendId(userId);
        if(StringUtil.isNotEmpty(list)){
            for(User u:list){
                if(!userId.equals(u.getId()))//防止推荐人是自己的情况下 出现的死循环
                    getTotalOrder(u.getId(),total);
            }
        }
    }



    private class CalFlThread implements Runnable{

        private Order order;
        private boolean hasGold = false;
        private boolean hasGeneral = false;
        private boolean hasParnter = false;
        private boolean hasOutGold = false;
        private boolean hasOutGeneral = false;
        private boolean hasOutParnter = false;
        private String initType = "";
        private String Customer = ConfigHelper.GetInstance().GetConfig("Customer_Zjcd");
        private String Member = ConfigHelper.GetInstance().GetConfig("Member_Zjcd");
        private List<User> userlist = new LinkedList<>();

        public CalFlThread(Order order) {
            this.order = order;
        }

        @Override
        public void run() {
            //String id = order.getMemberId();
            List<OrderProduct> list = orderProductDao.listByOrderId(order.getId());
            List<Product> data = new ArrayList<>();
            for(OrderProduct op:list){
                Product product = baseMyBatisDao.findById(ProductDao.class,op.getProductId());
                if(product.getStock()>0){//减少库存
                    product.setStock(product.getStock()-1);
                }
                product.setSaleCount((int)(Float.parseFloat(StringNumber.add(product.getSaleCount() + "", op.getNum()))));
                baseMyBatisDao.update(ProductDao.class, product);


                product.setNum(op.getNum());
                ProductParam productParam = baseMyBatisDao.findById(ProductParamDao.class,product.getId());
                product.setProductParam(productParam);
                data.add(product);
            }
            //找到下单人
            User user = baseMyBatisDao.findById(UserDao.class,order.getMemberId());
            initType = user.getType();
            boolean add = false;//是否在用户链表中加入普通用户
            if(MemberType.Customer.name().equals(initType)){//如果是普通用户
                add = true;
            }
            getRecommendUser(user,add);
            if(user.getType().equals(MemberType.General.name())&&("1".equals(user.getIsPartner()))){//全国总代
                initType = MemberType.Partner.name();
            }
            calFl(data);
            //找到区域合伙人 返利3%
            String autoFh = ConfigHelper.GetInstance().GetConfig("AutoFh");
            if("1".equals(autoFh)){//开启自动分红
                autoFhToPartner(order);
            }

        }

        /**
         * 递归查找到上级推荐人
         * @param user
         */
        private void getRecommendUser(User user,boolean need) {
            String id = user.getRecommendId();
            if(StringUtil.isNotNull(id)&&!id.equals(user.getId())) {
                User ruser = baseMyBatisDao.findById(UserDao.class,id);
                if(ruser!=null){
                    if(!need){
                        if(!MemberType.Customer.name().equals(ruser.getType())){
                            userlist.add(ruser);
                        }
                    }else{
                        userlist.add(ruser);
                    }
                    if(!MemberType.Customer.name().equals(ruser.getType())){
                        need = false;
                    }
                    if(!id.equals(user.getId()))
                        getRecommendUser(ruser,need);
                }
            }
        }

        //计算返利
        private void calFl(List<Product> list){
            for(int i=0;i<userlist.size();i++){
                User user = userlist.get(i);
                if(i<3){//判断是否三级内
                    calIn(user,list,i);
                }else{
                    calOut(user,list,i);
                }
            }

        }

        /**
         * 计算三级外
         * @param user
         * @param list
         * @param level
         */
        private void calOut(User user, List<Product> list, int level) {
            if(initType.equals(MemberType.Customer.name())){
                if(MemberType.Gold.name().equals(user.getType())){
                    if(!hasGold&&!hasGeneral&&!hasParnter&&!hasOutGold&&!hasOutGeneral&&!hasOutParnter){
                        if(!user.getType().equals(MemberType.Customer.name())){//只要不是普通消费者
                            for(Product product:list){
                                calInProduct(product,user,false,level);
                            }
                        }
                       hasOutGold = true;
                    }
                }else if(MemberType.General.name().equals(user.getType())&&(!"1".equals(user.getIsPartner()))){
                    if(!hasGeneral&&!hasParnter&&!hasOutGeneral&&!hasOutParnter){
                        for(Product product:list){
                            calInProduct(product,user,false,level);
                        }
                    }
                    hasOutGeneral = true;
                }else if(MemberType.General.name().equals(user.getType())&&("1".equals(user.getIsPartner()))){
                    if(!hasGold&&!hasGeneral&&!hasParnter&&!hasOutGeneral&&!hasOutParnter){
                        for(Product product:list){
                            calInProduct(product,user,false,level);
                        }
                    }else if(hasGold&&!hasGeneral&&!hasParnter&&!hasOutGeneral&&!hasOutParnter){
                        for(Product product:list){
                            calInProduct(product,user,false,level);
                        }
                    }
                    hasOutParnter = true;
                }else if(MemberType.Partner.name().equals(user.getType())){
                    if(!hasGeneral&&!hasParnter&&!hasOutGeneral&&!hasOutParnter){
                        for(Product product:list){
                            calInProduct(product,user,false,level);
                        }
                    }
                    hasOutParnter = true;
                }
            }
        }

        /**
         * 计算三级内
         * @param user
         * @param list
         * @param level
         */
        private void calIn(User user, List<Product> list, int level) {
            if(initType.equals(MemberType.Customer.name())){//下单人是普通消费者
                initIsCustomer(user,list,true,level);
            }else if(initType.equals(MemberType.Gold.name())){//下单人是金牌代理
                hasGold = true;
                initIsGold(user,list,true,level);
            }else if(initType.equals(MemberType.General.name())&&(!"1".equals(user.getIsPartner()))){//下单人是全国总代  其商家谁也吃不到返现
                hasGeneral = true;
            }else if(initType.equals(MemberType.General.name())&&("1".equals(user.getIsPartner()))){//下单人是全国总代  其商家谁也吃不到返现
                hasGeneral = true;
            }else if(initType.equals(MemberType.Partner.name())){
                hasParnter = true;
            }
        }

        /**
         * 如果下单人是金牌代理
         * @param user
         * @param list
         */
        private void initIsGold(User user, List<Product> list,boolean isIn,int level) {
            if(MemberType.General.name().equals(user.getType())&&(!"1".equals(user.getIsPartner()))){//如果是全国总代
                if(!hasGeneral&&!hasParnter){//如果没有全国总代和区域合伙人
                    for(Product product:list){
                        calInProduct(product,user,isIn,level);
                    }
                }
                hasGeneral = true;
            }else if(MemberType.General.name().equals(user.getType())&&("1".equals(user.getIsPartner()))){//区域合伙人
                if(!hasParnter){
                    user.setType("1");
                    for(Product product:list){
                        calInProduct(product,user,isIn,level);
                    }
                }
                hasParnter = true;
            }else if(MemberType.Partner.name().equals(user.getType())){//如果是区域合伙人
                if(!hasParnter){
                    user.setType("1");
                    for(Product product:list){
                        calInProduct(product,user,isIn,level);
                    }
                }
                hasParnter = true;
            }
        }

        /**
         * 如果下单时普通消费者的计算
         * @param user
         * @param list
         */
        private void initIsCustomer(User user,List<Product> list,boolean isIn,int level) {
            if(MemberType.Customer.name().equals(user.getType())){//上级是普通消费者
                if(!hasGold&&!hasGeneral&&!hasParnter){//之前全部是普通消费者
                    for(Product product:list){
                        calInProduct(product,user,isIn,level);
                    }
                }
            }else if(MemberType.Gold.name().equals(user.getType())){
                if(!hasGold&&!hasGeneral&&!hasParnter){//之前全部是普通消费者
                    for(Product product:list){
                        calInProduct(product,user,isIn,level);
                    }
                    hasGold = true;
                }
            }else if(MemberType.General.name().equals(user.getType())&&(!"1".equals(user.getIsPartner()))){
                if((!hasGold&&!hasGeneral&&!hasParnter)||(hasGold&&!hasGeneral)){
                    for(Product product:list){
                        calInProduct(product,user,isIn,level);
                    }
                    hasGeneral = true;
                }
            }else if(MemberType.General.name().equals(user.getType())&&("1".equals(user.getIsPartner()))){
                if((!hasGold&&!hasGeneral&&!hasParnter)){
                    for(Product product:list){
                        calInProduct(product,user,isIn,level);
                    }
                    hasGeneral = true;
                }else{
                    if(hasGold&&!hasGeneral&&!hasParnter){
                        user.setType("1");
                        for(Product product:list){
                            calInProduct(product,user,isIn,level);
                        }
                        hasGeneral = true;
                    }
                }
            }else if(MemberType.Partner.name().equals(user.getType())){
                if((!hasGold&&!hasGeneral&&!hasParnter)||hasGold||hasParnter){
                    for(Product product:list){
                        calInProduct(product,user,isIn,level);
                    }
                    hasParnter = true;
                }
            }
        }

        /**
         * 计算具体的明细
         * @param product
         * @param user
         */
        private void calInProduct(Product product, User user,boolean isIn,int level) {
            ProductParam param = product.getProductParam();
            String num = product.getNum();
                String amount = "0";
                String base = Member;

                if(user.getType().equals(MemberType.Customer.name())){//如果是普通会员
                    if(isIn) {
                        amount = param.getMemberIn();
                    }
                    base = Customer;
                }else if(user.getType().equals(MemberType.Gold.name())){
                    if(isIn) {
                        amount = param.getGoldIn();
                    }else{
                        amount = param.getGoldOut();
                    }
                }else if(user.getType().equals(MemberType.General.name())&&(!"1".equals(user.getIsPartner()))){
                    if(isIn) {
                        if(hasGold){
                            amount = param.getGeneralGoldIn();
                        }else {
                            amount = param.getGeneralIn();
                        }
                    }else{
                        if(hasGold){
                            amount = param.getGeneralGoldOut();
                        }else {
                            if (hasOutGold) {
                                amount = param.getGeneralGoldOut();
                            } else {
                                amount = param.getGeneralOut();
                            }
                        }
                    }
                }else if(user.getType().equals(MemberType.General.name())&&("1".equals(user.getIsPartner()))){
                    if(isIn) {
                        if(!hasGold&&!hasGeneral&&!hasParnter) {
                            amount = param.getPartnerIn();
                        }else if(hasGold&&!hasGeneral&&!hasParnter){
                            amount = param.getGeneralGoldIn();
                        }
                    }else{
                        if(!hasGold&&!hasGeneral&&!hasParnter&&!hasOutGold&&!hasOutGeneral&&!hasOutParnter) {
                            amount = param.getPartnerOut();
                        }else if(hasGold&&!hasGeneral&&!hasOutGeneral){
                            amount = param.getGeneralGoldIn();
                        }else if(hasOutGold&&!hasGeneral&&!hasOutGeneral){
                            amount = param.getGeneralGoldOut();
                        }
                    }
                }else if(user.getType().equals("1")){
                   /* if(isIn) {
                        if(!hasGeneral&&!hasParnter)
                            amount = param.getGeneralGoldIn();
                    }else{
                        if(!hasGeneral&&!hasOutGeneral&&!hasParnter&&!hasOutParnter)
                            amount = param.getGeneralGoldOut();
                    }*/
                    if(isIn) {
                        if(!hasGold&&!hasGeneral&&!hasParnter) {
                            amount = param.getPartnerIn();
                        }else if(hasGold&&!hasGeneral&&!hasParnter){
                            amount = param.getGeneralGoldIn();
                        }
                    }else{
                        if(!hasGold&&!hasGeneral&&!hasParnter&&!hasOutGold&&!hasOutGeneral&&!hasOutParnter) {
                            amount = param.getPartnerOut();
                        }else if(hasGold&&!hasGeneral&&!hasOutGeneral){
                            amount = param.getGeneralGoldIn();
                        }else if(hasOutGold&&!hasGeneral&&!hasOutGeneral){
                            amount = param.getGeneralGoldOut();
                        }
                    }
                }

                if(!amount.equals("0")) {
                    List<Order> orderlist = orderDao.listByUserId(user.getId());
                    //普通用户只有下单时才会有返现
                    if((user.getType().equals(MemberType.Customer.name())&&(StringUtil.isNotEmpty(orderlist)))||(!user.getType().equals(MemberType.Customer.name()))){
                        String bonus = StringNumber.mul(StringNumber.mul(amount, base), num);
                        String cash = StringNumber.sub(StringNumber.mul(amount, num), bonus);

                        List<UserMoney> moneys = userMoneyDao.findByUserId(user.getId());
                        boolean needSave = false;
                        UserMoney money = null;
                        if(StringUtil.isNotEmpty(moneys))
                            money = moneys.get(0);
                        if (money==null) {
                            money = new UserMoney();
                            money.setId(UUIDFactory.random());
                            money.setUserId(user.getId());
                            money.setUserName(user.getNickName());
                            needSave = true;
                        }
                        String beforeCash = money.getCash();
                        String beforeBonus = money.getBonus();
                        money.setCash(StringNumber.add(beforeCash, cash));
                        money.setBonus(StringNumber.add(beforeBonus, bonus));
                        money.setTotalAmount(StringNumber.add(StringNumber.add(money.getTotalAmount(), cash), bonus));
                        if (needSave) {
                            baseMyBatisDao.insert(UserMoneyDao.class, money);
                        } else {
                            baseMyBatisDao.update(UserMoneyDao.class, money);
                        }
                        //保存订单返现记录
                        String fxAmount = StringNumber.mul(amount, num);
                        saveOrderFx(user,order,fxAmount);

                        String content = "";
                        //发送模板消息
                        if (StringUtil.isNotNull(user.getOpenId())) {
                            User orderUser = baseMyBatisDao.findById(UserDao.class, order.getMemberId());
                            if (level < 3) {
                                if(level<0)
                                    level = 0;
                                level ++;
                                content = "您的" + level + "级会员" + order.getUserName()+"("+orderUser.getAccount() + ")购买产品(" + product.getName() + "*"+num+")";
                            } else {
                                content = "您的下级会员" + order.getUserName()+"("+orderUser.getAccount() + ")购买产品(" + product.getName()  + "*"+num+")";
                            }
                           String url = templateMessageUrl+user.getId();
                           SendMessageUtil.sendMessage(user.getOpenId(), url, content, new Date().getTime(), fxAmount + "元");
                            //0505 如果当前是全国总代 则找齐上家  上家如果是全国总代 则赠送零售分红
                            if(MemberType.General.name().equals(user.getType())){//全国总代
                                if(StringUtil.isNotNull(user.getRecommendId())&&!user.getRecommendId().equals(user.getId())) {
                                    User upuser = baseMyBatisDao.findById(UserDao.class, user.getRecommendId());
                                    if (upuser != null && (MemberType.General.name().equals(user.getType()))) {//上家是全国总代
                                        String retailFee = ConfigHelper.GetInstance().GetConfig("RetailFee");
                                        String retailAmount = StringNumber.div(StringNumber.mul(fxAmount, retailFee), "100");

                                        saveRetailAmount(upuser, retailAmount, user, product, num);
                                    }
                                }
                            }
                        }
                        //保存日志
                        saveAmountLog(user, beforeCash, beforeBonus, cash, bonus, money.getCash(), money.getBonus(), money.getFrozenAmount(),content);
                    }
                }
        }

        /**
         * 零售分红奖励
         * @param upuser
         * @param retailAmount
         */
        private void saveRetailAmount(User upuser, String retailAmount, User user, Product product,String num) {
            try {
                List<UserMoney> upmoneys = userMoneyDao.findByUserId(upuser.getId());
                boolean upneedSave = false;
                UserMoney upmoney = null;
                if (StringUtil.isNotEmpty(upmoneys))
                    upmoney = upmoneys.get(0);
                if (upmoney == null) {
                    upmoney = new UserMoney();
                    upmoney.setId(UUIDFactory.random());
                    upmoney.setUserId(upuser.getId());
                    upmoney.setUserName(upuser.getNickName());
                    upneedSave = true;
                }
                String upbeforeCash = upmoney.getCash();
                upmoney.setCash(StringNumber.add(upbeforeCash, retailAmount));
                upmoney.setTotalAmount(StringNumber.add(upmoney.getTotalAmount(), retailAmount));
                if (upneedSave) {
                    baseMyBatisDao.insert(UserMoneyDao.class, upmoney);
                } else {
                    baseMyBatisDao.update(UserMoneyDao.class, upmoney);
                }
                saveOrderFx(upuser, order, retailAmount);

                String content = "您的下级会员" + order.getUserName() + "(" + user.getAccount() + ")购买产品(" + product.getName() + "*" + num + ")，获得零售奖励";
                String upurl = templateMessageUrl + upuser.getId();
                SendMessageUtil.sendMessage(upuser.getOpenId(), upurl, content, new Date().getTime(), retailAmount + "元");
                saveAmountLog(upuser, upbeforeCash, upmoney.getBonus(), retailAmount, upmoney.getBonus(), upmoney.getCash(), upmoney.getBonus(), upmoney.getFrozenAmount(), content);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        private void saveAmountLog(User user,String beforeCash,String beforeBonus,String cash,String bonus,String afterCash,String afterBonus,String frozenAmount,String content){
            AmountLog log = new AmountLog();
            log.setId(UUIDFactory.random());
            log.setUserId(user.getId());
            log.setUserName(user.getNickName());
            log.setCreateTime(new Date().getTime());
            log.setBeforeCash(beforeCash);
            log.setBeforeBonus(beforeBonus);
            log.setCash(cash);
            log.setBonus(bonus);
            log.setAfterCash(afterCash);
            log.setAfterBonus(afterBonus);
            log.setType(AmountType.FxFee.name());
            log.setBeforeFrozenAmount(frozenAmount);
            log.setAfterFrozenAmount(frozenAmount);
            log.setDataName(content);
            baseMyBatisDao.insert(AmountLogDao.class,log);
        }
    }

    /**
     * 自动分红
     * @param order
     */
    private void autoFhToPartner(Order order) {
        //先找到订单所在区域的区域合伙人
        //先找区县级
        List<User> list = userDao.listUserByCity("3",order.getProvince(),order.getCity(),order.getArea());
        if(!StringUtil.isNotEmpty(list)){
            //再找地市级
            list = userDao.listUserByCity("2",order.getProvince(),order.getCity(),order.getArea());
        }
        if(!StringUtil.isNotEmpty(list))
            //再找副省级
            list = userDao.listUserByCity("1",order.getProvince(),order.getCity(),order.getArea());
        if(!StringUtil.isNotEmpty(list))
            //再找省级
            list = userDao.listUserByCity("0",order.getProvince(),order.getCity(),order.getArea());
        if(StringUtil.isNotEmpty(list)){
            User user = list.get(0);
            List<UserMoney> moneys = userMoneyDao.findByUserId(user.getId());
            if(StringUtil.isNotEmpty(moneys)){
                UserMoney money = moneys.get(0);
                String amount = StringNumber.mul(order.getTotalMoney(),"0.03");
                String beforeCash = money.getCash();
                money.setCash(StringNumber.add(money.getCash(),amount));
                this.baseMyBatisDao.update(UserMoneyDao.class,money);

                saveAmountLog(user,beforeCash,money.getBonus(),amount,money,AmountType.QyFee.name());

                String url = templateMessageUrl+user.getId();
                String content = "";
                if(order.getType().equals("0")){
                    content = "会员" + order.getUserName()+ "购物下单，获得区域奖励";
                }else{
                    content = "会员" + order.getUserName()+ "升级" + (order.getProductName().equals(MemberType.General.name())?"全国总代":"金牌代理")+"，获得区域奖励";
                }
               SendMessageUtil.sendMessage(user.getOpenId(), url, content, new Date().getTime(), amount + "元");
            }
        }
    }

    /**
     * 保存订单返现记录
     * @param user
     * @param order
     */
    private void saveOrderFx(User user, Order order,String amount) {
        OrderFx dto = new OrderFx();
        dto.setId(UUIDFactory.random());
        dto.setUserId(user.getId());
        dto.setUserAccount(user.getAccount());
        dto.setOrderId(order.getId());
        dto.setOrderNo(order.getNo());
        dto.setAmount(amount);
        dto.setCreateTime(new Date().getTime());
        dto.setType(order.getType());
        this.baseMyBatisDao.insert(OrderFxDao.class,dto);
    }
    private class CalSjThread implements Runnable{

        private Order order;
        private boolean hasGold = false;
        private boolean hasGeneral = false;
        private boolean hasParnter = false;
        private String initType = "";
        ConfigHelper instance = ConfigHelper.GetInstance();
        private String Customer = instance.GetConfig("Customer_Zjcd");
        private String Member = instance.GetConfig("Member_Zjcd");
        private String Gold_Fee = instance.GetConfig("Gold_Amount");
        private String General_Fee = instance.GetConfig("General_Amount");
        private List<User> userlist = new LinkedList<>();

        public CalSjThread(Order order) {
            this.order = order;
        }

        @Override
        public void run() {
           // String openId = order.getMemberId();
            ConfigHelper instance = ConfigHelper.GetInstance();
            String gold_fee = instance.GetConfig("Gold_Fee");
            String general_fee = instance.GetConfig("General_Fee");
            //找到下单人
            User user = baseMyBatisDao.findById(UserDao.class,order.getMemberId());
            //更新订单人的类型
            if(order.getProductName().equals(MemberType.Gold.name())&&gold_fee.equals(order.getTotalMoney())){
                user.setType(MemberType.Gold.name());
            }else if(order.getProductName().equals(MemberType.General.name())&&general_fee.equals(order.getTotalMoney())){
                user.setType(MemberType.General.name());
            }
            User upperUser = getUserUpper(user);
            if(upperUser!=null)
              //user.setRecommendId(upperUser.getOpenId());
                user.setRecommendId(upperUser.getId());
            baseMyBatisDao.update(UserDao.class,user);
            getRecommendUser(user);
            calFl(user);
            String autoFh = ConfigHelper.GetInstance().GetConfig("AutoFh");
            if("1".equals(autoFh)){//开启自动分红
                autoFhToPartner(order);
            }
        }

        /**
         * 将其上级为普通消费者的剔除
         * @param user
         */
        private User getUserUpper(User user) {
            if(!user.getRecommendId().equals(user.getId())) {
                User upUser = baseMyBatisDao.findById(UserDao.class, user.getRecommendId());
                if (upUser != null) {
                    if (!upUser.getType().equals(MemberType.Customer.name())) {//不等于普通消费者的话
                        return upUser;
                    } else {
                        return getUserUpper(upUser);
                    }
                }
            }
            return null;
        }


        /**
         * 递归查找到上级推荐人
         * @param user
         */
        private void getRecommendUser(User user) {
            String id = user.getRecommendId();
            if(StringUtil.isNotNull(id)&&!id.equals(user.getId())) {
                User ruser = baseMyBatisDao.findById(UserDao.class,id);
                if(ruser!=null&&"1".equals(ruser.getIsMember())){
                    //将普通消费者剔除
                    if(!ruser.getType().equals(MemberType.Customer.name()))
                        userlist.add(ruser);
                    if(!id.equals(user.getId()))
                        getRecommendUser(ruser);
                }
            }
        }

        //计算返利
        private void calFl(User user){
            if(user.getType().equals(MemberType.Gold.name())){//用户类型是金牌代理
                goldMemberUp();
            }else if(user.getType().equals(MemberType.General.name())){
                generalMemberUp();
            }
        }
        /**
         * 金牌代理升级
         * 三级内如果没有出现全国总代 则奖励全部的金牌代理Gold_Fee
         * 三级内如果出现全国总代 则奖励全国总代  之后的不再奖励
         * 三级外如果出现全国总代  且三级内没有出现全国总代  则奖励全国总代  退出循环
         */
        private void goldMemberUp() {
            boolean isBreak = false;
            int generalCnt = 0;
            int general1 = -1;
            int general2 = -1;
            int general3 = -1;
            for(int i=0;i<userlist.size();i++){
                User upuser = userlist.get(i);
                if(upuser.getType().equals(MemberType.Gold.name())){//存在金牌会员
                    if(!hasGeneral)
                        calMoney(upuser,Gold_Fee,AmountType.GoldFee.name(),i);
                }else if(upuser.getType().equals(MemberType.General.name())){
                    if(!hasGeneral) {
                        general1 = i;
                        calMoney(upuser, Gold_Fee,AmountType.GoldFee.name(),i);
                    }else{
                        if(general1>-1){
                            if(general2>-1){
                                general3 = i;
                                if(((general3 - general2)==1)&&((general2-general1)==1)){
                                    calMoney(upuser, Gold_Fee,AmountType.GoldFee.name(),i);
                                    isBreak = true;
                                }else{
                                    isBreak = true;
                                }
                            }else{
                                general2 = i;
                                if((general2-general1)==1){
                                    calMoney(upuser, Gold_Fee,AmountType.GoldFee.name(),i);
                                }
                            }
                        }
                    }
                    hasGeneral = true;
                }
                if(isBreak)
                    break;
            }

        }

        /**
         * 计算全国总代返现奖励
         */
        private void generalMemberUp(){
            boolean isBreak = false;
            int generalCnt = 0;
            for(int i=0;i<userlist.size();i++){
                User upuser = userlist.get(i);
                if(i==0){//判断上面第一个角色
                    if(upuser.getType().equals(MemberType.Gold.name())){
                        calMoney(upuser,General_Fee,AmountType.GeneralFee.name(),i);
                        hasGold = true;
                    }else if(upuser.getType().equals(MemberType.General.name())){
                        calMoney(upuser,General_Fee,AmountType.GeneralFee.name(),i);
                        hasGeneral = true;
                        generalCnt ++;
                    }
                }else if(i==1){
                    if(upuser.getType().equals(MemberType.General.name())){//只会全国总代才会吃
                        calMoney(upuser,General_Fee,AmountType.GeneralFee.name(),i);
                        hasGeneral = true;
                        generalCnt ++;
                    }
                }else if(i==2){
                    if(upuser.getType().equals(MemberType.General.name())){//只会全国总代才会吃
                        calMoney(upuser,General_Fee,AmountType.GeneralFee.name(),i);
                        hasGeneral = true;
                        generalCnt ++;
                    }
                }else{
                    break;
                }
            }
        }

        /**
         * 计算升级返现
         * 不分流
         * @param user
         * @param amount
         * @param type
         */
        private void calMoney(User user,String amount,String type,int level){
            List<UserMoney> moneys = userMoneyDao.findByUserId(user.getId());
            UserMoney money = null;
            if(StringUtil.isNotEmpty(moneys))
                money = moneys.get(0);
            boolean needSave = false;
            if(money==null){
                money = new UserMoney();
                money.setId(UUIDFactory.random());
                money.setUserId(user.getId());
                money.setUserName(user.getNickName());
                needSave = true;
            }
            String beforeCash = money.getCash();
            String beforeBonus = money.getBonus();
            money.setCash(StringNumber.add(beforeCash,amount));
            money.setTotalAmount(StringNumber.add(money.getTotalAmount(),amount));
            if(needSave){
                baseMyBatisDao.insert(UserMoneyDao.class, money);
            }else {
                baseMyBatisDao.update(UserMoneyDao.class, money);
            }
            //保存日志
            saveAmountLog(user,beforeCash,beforeBonus,amount,"0",money.getCash(),money.getBonus(),type,money.getFrozenAmount());
            //保存返现记录
            saveOrderFx(user,order,amount);

            String content = "";
            //发送模板消息
            if (StringUtil.isNotNull(user.getOpenId())) {
                User orderUser = baseMyBatisDao.findById(UserDao.class, order.getMemberId());
                if(orderUser.getType().equals(MemberType.Gold.name())||orderUser.getType().equals(MemberType.General.name())){
                    if (level < 3) {
                        if(level<0)
                            level = 0;
                        level ++;
                        content = "您的" + level + "级会员" + order.getUserName()+"("+orderUser.getAccount() + ")升级" + (orderUser.getType().equals(MemberType.General.name())?"全国总代":"金牌代理");
                    } else {
                        content = "您的下级会员" + order.getUserName()+"("+orderUser.getAccount() + ")升级" + (orderUser.getType().equals(MemberType.General.name())?"全国总代":"金牌代理");
                    }
                    String url = templateMessageUrl+user.getId();
                    SendMessageUtil.sendMessage(user.getOpenId(), url, content, new Date().getTime(), amount + "元");
                }
            }
        }

        private void saveAmountLog(User user,String beforeCash,String beforeBonus,String cash,String bonus,String afterCash,String afterBonus,String type,String frozenAmount){
            AmountLog log = new AmountLog();
            log.setId(UUIDFactory.random());
            log.setUserId(user.getId());
            log.setUserName(user.getNickName());
            log.setCreateTime(new Date().getTime());
            log.setBeforeCash(beforeCash);
            log.setBeforeBonus(beforeBonus);
            log.setCash(cash);
            log.setBonus(bonus);
            log.setAfterCash(afterCash);
            log.setAfterBonus(afterBonus);
            log.setType(type);
            log.setBeforeFrozenAmount(frozenAmount);
            log.setAfterFrozenAmount(frozenAmount);
            baseMyBatisDao.insert(AmountLogDao.class,log);
        }
    }

}
